local skynet = require "skynet"
local filelog = require "filelog"
local filename = "gatenodesocket.lua"

local configdao = require "configdao"
local timetool = require "timetool"
local md5 = require "md5"

local service = nil
local GatenodeSocket = {
	service = nil
}

local login2gate_key = nil

function GatenodeSocket.process(session, source, event, ...)
	-- 确定只进行一次赋值
	if not service then
		service = GatenodeSocket.service
		login2gate_key = configdao.get_cfgsvrs_key("login2gate_key")
	end
	
	local f = GatenodeSocket[event] 
	if f == nil then
		filelog.sys_error(filename.." line25 GatenodeSocket.process invalid event:"..event)
		return nil
	end
	f(...)	 
end

function GatenodeSocket.open(fd, ip)
	local service = GatenodeSocket.service
	service.tcpmng.open_socket(fd, ip)
end

function GatenodeSocket.close(fd)
	local service = GatenodeSocket.service
	service.tcpmng.close_socket(fd)
end

function GatenodeSocket.error(fd, msg)
	local service = GatenodeSocket.service
	service.tcpmng.close_socket(fd)
end

function GatenodeSocket.warning(fd, size)
	-- size K bytes havn't send out in fd
	filelog.sys_warning(filename.." line48 lineGatenodeSocket warning:"..size.." K bytes havn't send out in "..fd)
end

--[[
// 现在data中进行token验证，正确后，才去进行和agent的绑定
// gatetoken = md5(rid + tokentime + login2gate_key ）+ tokentime
message entergame{
	required int32  uid		 = 1;	//玩家的uid
	required int32  rid		 = 2;	//玩家的rid
	required string gatetoken   = 3;	//去gate验证的 token， 
	required int32  expiretime  = 4;	//token过期时间，绝对时间戳
	optional string clientver   = 5;	//client 的资源小版本号
}

message entergameR{
	required int32 isreauth	 = 1;		//是否需要重新认证，断线重连时根据token是否过期告诉client是否需要重新登录认证, 0表示false、1表示true
	required int32 servertime   = 2;	//同步服务器时间
	required roleinfo baseinfo  = 3;
	optional string gamenode  = 4;	//用户所在游戏
	optional int32 table_index= 5;	//桌子的索引
}
]]
function GatenodeSocket.data(fd, msg, sz, realip)
	local service = GatenodeSocket.service
	local msghead, msgbody = service.decode.c2sunpack(service.protobuf, msg)
	if msghead == nil or msghead.msgname ~= "entergame" then
		service:send_resmsgto_client(fd, "entergameR", _, 1, "must be entergame msg")
		service.tcpmng.close_socket(fd)
		return
	end	
	if msghead.msgname == "entergame" then
		-- 验证判断 loginnode 过来的token,通过后，通过create_session 给agent处理
		-- todo，是否验证token生成时间
		local tokentime = string.sub(msgbody.gatetoken, 33)
		local newtoken = md5.sumhexa(msgbody.rid .. tokentime .. login2gate_key ) .. tokentime
		if(newtoken ~= msgbody.gatetoken) then
			service:send_resmsgto_client(fd, "entergameR", _, 2, "erro:1, gatetoken error")
			service.tcpmng.close_socket(fd)
			return
		end

        --检测客户端版本,版本不匹配，踢掉
        local clientver = skynet.call(".router","lua","getclientver")
        if msgbody.clientver ~= clientver and msgbody.clientver ~= "0000" then
            service:send_resmsgto_client(fd, "kickroleN", {rid = msgbody.rid})
            service:send_resmsgto_client(fd, "messagetipsN", {tips = "客户端有更新，请退出游戏重新登陆"})
			service.tcpmng.close_socket(fd)
            return
        end

        --检测玩家是否被封号，封号踢掉
        local isblocked = skynet.call(".router","lua","check_rid_isblocked",msgbody.rid)
        if isblocked then
            service:send_resmsgto_client(fd, "entergameR", _,2, "账号存在异常，请联系客服（" .. tostring(msgbody.rid) .. "）")
			service.tcpmng.close_socket(fd)
            return
        end

        --检测是否开启白名单，且是否在白名单列表
        local iswhitelist = skynet.call(".router","lua","check_rid_iswhitelist",msgbody.rid)
        if not iswhitelist then
            service:send_resmsgto_client(fd, "entergameR", _,2, "游戏暂未开放,请稍后重试")
			service.tcpmng.close_socket(fd)
            return
        end

		local result = service.tcpmng.create_session(fd, "entergame", msgbody, realip)
        if not result then
            service:send_resmsgto_client(fd, "entergameR", _,-99, "登录游戏失败")
        end
	end
end

return GatenodeSocket